<script lang="ts" setup>
import type { SysLogVO } from '@/api/syslog/sysLogType'
import { getSysLogDetail, getSysLogPage } from '@/api/syslog/sysLogApi'
import useLayoutStore from '@/store/modules/setting'
import { ElMessage } from 'element-plus'
import { onMounted, ref } from 'vue'

// 定义响应式数据-用户名
const userName = ref<string>('')
// 默认页码
const currentPage = ref<number>(1)
// 默认页行数
const pageSize = ref<number>(10)
// 数据总数
const total = ref<number>(0)
// 系统日志
const sysLogList = ref<SysLogVO[]>([])
// 使用layout组件小仓库
const layoutStore = useLayoutStore()
// 定义响应式数据 dialogVisible 控制对话框的显示与隐藏
const dialogVisible = ref<boolean>(false)
// 定义响应式数据 textarea 控制日志详情对话框中的文本域
const textarea = ref<string>('')

/**
 * 默认分页查询
 * 当前第一页
 * 每页10条数据
 */
onMounted(() => {
  // 设置当前页码为1
  currentPage.value = 1
  // 设置每页数据条数10
  pageSize.value = 10
  // 设置 userName 为空
  userName.value = ''
  getSysLogPageData()
})

/**
 * 异步获取系统日志分页数据
 * 此函数用于根据当前页码、页面大小和用户名筛选条件，获取系统日志的分页数据
 * 它通过调用后端接口来获取数据，并在成功时更新系统日志列表和总记录数
 * 在发生错误时，它会捕获异常并显示错误消息
 */
async function getSysLogPageData() {
  try {
    // 调用分页查询接口
    const result: any = await getSysLogPage({
      userName: userName.value,
      pageReq: {
        current: currentPage.value,
        size: pageSize.value,
      },
    })
    // 检查结果是否成功
    if (result.success && result.code === 200) {
      sysLogList.value = result.data
      total.value = result.total
    }
  }
  catch (error) {
    // 处理异常
    let errorMessage = '未知错误'
    if (error instanceof Error) {
      errorMessage = error.message
    }
    // 显示错误消息
    ElMessage({
      message: `查询失败: ${errorMessage || '未知错误'}`,
      type: 'error',
    })
  }
}

// 重置界面
function reset() {
  layoutStore.refresh = !layoutStore.refresh
}

// 分页器下拉菜单自定义事件
function handerPageData() {
  getSysLogPageData()
}

async function getSysLogDetailById(row: SysLogVO) {
  try {
    // 调用接口获取详细数据
    const result: any = await getSysLogDetail({
      id: row.extId,
    })
    // 检查结果是否成功
    if (result.success && result.code === 200) {
      // 深拷贝一份数据对象，避免直接修改响应式数据
      const dataCopy = { ...result.data }
      // 对嵌套的 JSON 字符串进行解析
      if (typeof dataCopy.requestParams === 'string') {
        dataCopy.requestParams = safeParse(dataCopy.requestParams)
      }
      if (typeof dataCopy.responseResult === 'string') {
        dataCopy.responseResult = safeParse(dataCopy.responseResult)
      }
      textarea.value = JSON.stringify(dataCopy, null, 2)
      // 打开对话框，打开之前先清空数据
      dialogVisible.value = true
    }
  }
  catch (error) {
    // 处理异常
    let errorMessage = '未知错误'
    if (error instanceof Error) {
      errorMessage = error.message
    }
    // 显示错误消息
    ElMessage({
      message: `查询失败: ${errorMessage || '未知错误'}`,
      type: 'error',
    })
  }
}

// 封装一个安全的 JSON 解析方法
function safeParse(value: any) {
  return JSON.parse(value)
}
</script>

<template>
  <!-- 查询条件 -->
  <el-card style="height: 75px;">
    <el-form :inline="true" class="form-inline">
      <el-form-item label="用户名">
        <el-input v-model="userName" placeholder="请输入用户名" />
      </el-form-item>
      <el-form-item>
        <el-button v-hasButton="`btn.syslog.page`" type="primary" icon="Search" @click="getSysLogPageData">
          查询
        </el-button>
        <el-button v-hasButton="`btn.syslog.page`" icon="Refresh" @click="reset">
          重置
        </el-button>
      </el-form-item>
    </el-form>
  </el-card>

  <!-- 查询结果列表 -->
  <el-card style="margin: 10px 0px;">
    <el-table style="margin: 10px 0px;" :data="sysLogList" :border="true">
      <el-table-column type="selection" align="center" width="50px" />
      <el-table-column type="index" label="#" align="center" width="50px" />
      <el-table-column prop="id" label="ID" align="center" width="200px" />
      <el-table-column prop="userName" label="用户名" align="center" />
      <el-table-column prop="callDate" label="接口调用日期" align="center" />
      <el-table-column prop="callTime" label="接口调用时间" align="center" />
      <el-table-column prop="url" label="接口请求 URL" align="center" width="300px" />
      <el-table-column prop="executionTime" label="接口执行时间（毫秒）" align="center" />
      <el-table-column prop="result" label="执行结果" align="center" />
      <el-table-column prop="extId" label="MongoDB中日志扩展记录ID" align="center" />
      <el-table-column label="操作" width="150px" align="center">
        <template #default="scope">
          <el-button type="primary" icon="Pointer" @click="getSysLogDetailById(scope.row)">
            扩展日志
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页器 -->
    <el-pagination
      v-model:current-page="currentPage"
      v-model:page-size="pageSize"
      :page-sizes="[10, 20, 30, 40, 50]"
      layout="prev, pager, next, jumper,->, sizes, total"
      :total="total"
      @current-change="getSysLogPageData"
      @size-change="handerPageData"
    />
  </el-card>

  <!-- 日志详情对话框 -->
  <el-dialog
    v-model="dialogVisible"
    title="日志详情"
    width="1800px"
  >
    <el-input
      v-model="textarea"
      style="width: 100%"
      :rows="25"
      type="textarea"
      placeholder="Please input"
      disabled
    />
    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="dialogVisible = false">
          确认
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<style scoped>
.form-inline {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
